home *** CD-ROM | disk | FTP | other *** search
-
-
-
- 185
-
- CHAPTER 18 - PORTS
-
-
- In order to communicate with the outside world, the outside world
- being your printer, your disk drives, your modem etc., the 8086
- uses ports. A port is an address distinct from a memory address
- where the i/o device can be reached.{1} When IBM set up the
- first PC, they decided what these port addresses would be and
- what the function of each bit at each address would be. Any VGA,
- EGA, CGA or monochrome card has to have it's ports at the same
- addresses as those set by IBM, and these ports have to do the
- same thing.
-
- Normally, an i/o device has more than one port address. The
- device not only has to transfer the data, it has to tell the
- computer whether it is ready, find out if the computer wants to
- send information, confirm that the transfer was successful etc.
- COM1 is port addresses 3F8 - 3FF. COM2 is 2F8 - 2FF. The CGA
- adapter is ports 3D0 - 3DF.
-
- In the CGA, port 3D9 sets the different colors. The 8086 writes
- to it, but can't read it. Port 3DA, it's neighbor, tells certain
- status information and is read only.
-
- All control information for the video cards is passed back and
- forth through the ports. However, the video card comes into
- memory 50 times a second to see what it should write to the
- screen. The characters on the screen don't pass through the
- ports. The mountain comes to Mohammed.
-
- The data does pass through a port on the way to your serial
- printer. The 8086 sends your printer control information through
- one port address and sends the data through a different port
- address.
-
- The port instructions can be either with AL or AX. AL and AX are
- the only registers you can use, AL for a byte transfer and AX for
- a word transfer. There are two forms to the input instruction:
-
- in al, port_address
- or
- in al, dx
-
- port_address is a constant and is limited to 0 - 255. It is a one
- byte constant. DX is the only register than can be used with the
- second form. DX can contain any number from 0 - 65535. The
- ____________________
-
- 1. There is memory address 0000 and there is port address
- 0000; they are two entirely different things. You can reach
- memory address 0000 with the DS:SI pair 0000:0000, but DS:SI
- can't get to port address 0000. The instruction "out 0, al"
- writes the contents of al to port address 0000, but the OUT
- instruction can't get anywhere near memory address 0000.
-
- ______________________
-
- The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson
-
-
-
-
- The PC Assembler Tutor 186
- ______________________
-
- following two pieces of code do the same thing:
-
- in al, 155
-
- mov dx, 155
- in al, dx
-
- This code moves one byte of data from port 155 to register AL.
-
- The output instruction is similar. We have:
-
- out port_address, al
- or
- out dx, al
-
- where port_address is a constant 0-255 and DX can contain a
- number 0 - 65535.
-
- out 97, ax
-
- moves a word from AX to port addresses 97-98. Notice that both
- the IN and the OUT instructions follow the DESTINATION, SOURCE
- ordering found in all the other 8086 instructions.
-
- The "in ax, port_address" form is not all that useful. If you
- look at the addresses for the video ports, for COM1 and COM2, you
- will see that they are all larger than 255. Also, most equipment
- can be at several different addresses. A modem can be at COM1,
- COM2, COM3, or COM4. If the port address is hard coded into the
- instructions, you need 4 subprograms to handle the 4 different
- addresses. It is easier to find out where the modem is, then use:
-
- modem_data_address dw ?
-
- mov dx, modem_data_address
- in al, dx
-
- and
- mov dx, modem_data_address
- out dx, al
-
- If you aren't planning on writing device drivers this is for
- background information only, since all standard i/o is done
- through DOS or BIOS interrupts.
-
- One last thing is the parity flag. It has been sitting on the
- screen with all the other flags. What is it for? When you send
- information over a modem, there is a large possibility of line
- interference. If it is text, and an occasional screw up is not
- too bad, using a parity check may be enough.{2} Parity can be
- even or odd. Even means that an even number of bits are set to 1;
- odd means that an odd number of bits are set to 1. This is not
- whether the number is even or odd, it is whether the number of 1
- ____________________
-
- 2. It is NEVER enough if you are transferring binary data or
- executable files.
-
-
-
-
- Chapter 18 - Ports 187
- __________________
-
- BITS is even or odd. Here's a short list.
-
- NUMBER BINARY PARITY
-
- 6 0110 even
- 7 0111 odd
- 8 1000 odd
- 9 1001 even
- 10 1010 even
-
- 8 is an even number but has odd parity, 9 is an odd number but
- has even parity. 6 has two 1 bits (even), 7 has three 1 bits
- (odd), 8 has one 1 bit (odd), 9 has two 1 bits (even) and 10 has
- two 1 bits (even).
-
- How does this help us? If there is a chance of 1/100 of screwing
- up a single bit in a byte, there is only a chance of 1/10,000 of
- screwing up two bits in a byte. What this means is that of every
- 100 errors, 99 of them will will be detectable because of a
- change in parity (by changing a bit from 0 to 1 or from 1 to 0)
- and only 1 of them will go undetected because two changes will
- keep the same parity. This is a little obscure, so make sure you
- understand why before continuing.
-
- This doesn't help us much yet, because we don't know what the
- parity was originally. 9 has even parity, 7 has odd parity. What
- communications programs do is FORCE the parity. They can either
- force it even or force it odd.
-
- The standard ASCII characters end at 127 - that is, 0111 1111
- (7F) is the highest legal number you can transmit. The left bit
- is unused, so we can use it to force the parity. We are going to
- force it even, but forcing it odd uses the same technique.
-
- The steps are:
-
- (1) Find the parity of the byte.
-
- (2) If it is even, leave it alone, if it is odd, put a 1 in
- the left hand bit. The parity is now even.
-
- If both the sending and receiving program have agreed on even
- parity, then on the receiving end, the program:
-
- (1) Checks for even parity. If the parity is odd, it is an
- error.
-
- (2) Puts a 0 back in the left hand bit. The original number
- is restored.
-
- We are going to make a loop with both parts and use show_regs to
- watch the parity flag. Here's the program:
-
- ; - - - - - - - - - - ENTER DATA BELOW THIS LINE
-
- error_banner db "Whoa! We have a screw up.", 13, 10, 0
-
-
-
-
-
- The PC Assembler Tutor 188
- ______________________
-
- ; - - - - - - - - - - ENTER DATA ABOVE THIS LINE
-
- ; - - - - - - - - - - ENTER CODE BELOW THIS LINE
- mov ax_byte, 0A3h ; al binary
- mov bx_byte, 0A2h ; unsigned half registers
- mov cx_byte, 0A2h ; unsigned half registers
- mov dx_byte, 0A3h ; dl binary
- lea ax, ax_byte
- call set_reg_style
-
- comm_loop:
- mov ax, 0
- call set_count ; reset count to 0
- mov bx, 0 ; clear registers
- mov cx, 0
- mov dx, 0
- call show_regs ; (1)
-
- ; the sending program
-
- call get_unsigned_byte
- and al, 7Fh ; 0111 1111 - make sure al < 128
- mov bl, al ; copy to bl
- call show_regs_and_wait ; (2)
-
- and al, al ; check parity
- call show_regs_and_wait ; (3)
-
- jpe do_nothing
- or al, 80h ; if parity odd, set left bit
-
- do_nothing:
- and al, al ; check parity for show_regs
- call show_regs_and_wait ; (4)
-
- ; the receiving program
-
- mov dl, al ; transmit from al to dl
- mov cl, dl ; copy to cl
- call show_regs_and_wait ; (5)
-
- and dl, dl
- jpe zero_left_bit ; is parity even?
- mov ax, error_banner
- call print_string
-
- zero_left_bit:
- and dl, 7Fh ; 0111 1111 binary, left bit 0
- mov cl, dl ; copy to cl
- call show_regs_and_wait ; (6)
- jmp comm_loop
-
- ; - - - - - - - - - - ENTER CODE ABOVE THIS LINE
-
- First, we set the register style so AL and DL are binary, BL and
- CL are unsigned. We'll use AL and BL for sending, CL and DL for
- receiving. Next, we reset the counter to 0 so we can see where we
-
-
-
-
- Chapter 18 - Ports 189
- __________________
-
- are, and zero AX, BX, CX, and DX. We get a byte and make sure
- that it is 127 or less,{3} then send a copy to BL. BL stays
- unchanged for the rest of the loop. We test the parity. and if it
- is odd, change it. Finally, we send it off to DL.
-
- On the receiving end, we test the parity. If it is odd, we print
- an error message. Then we zero the left hand bit. It is faster to
- zero the left hand bit than to check to see if it needs to be
- zeroed, so we do it for all data. The result is put in CL for
- comparison. AL and DL are shown in binary form so you can count
- the number of 1 bits in the byte.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ____________________
-
- 3. The following could happen if we didn't take this step. We
- get a number > 128 with odd parity. 131 (1000 0011 83h) is an
- example. The sending program sees that it is odd parity, so it
- puts a 1 in the left hand bit. But there is already a 1 in the
- left hand bit, so the parity doesn't change, it is odd. The
- receiving program gets the byte, tests it, notices that it is
- odd, and sends back a transmission error. Since the sending
- program didn't see anything wrong, it just sends the same byte
- again. It will never get through correctly. In real life, the
- sending program would probably test the byte to see if it was
- greater than 127 and print an error if it was.
-
-
-
-
- The PC Assembler Tutor 190
- ______________________
-
- SUMMARY
-
-
- POSSIBLE I/O INSTRUCTIONS
-
- in ax, constant (= port address 0 - 255)
- in ax, DX
-
- in al, constant (= port address 0 - 255)
- in al, DX
-
- out constant, ax (constant = port address 0 - 255)
- out DX, ax
-
- out constant, al (constant = port address 0 - 255)
- out DX, al
-
- In these instructions DX holds a port address and
- can be from 0 - 65535.
-
-
- PARITY
-
- Parity is whether the number of 1 bits in a byte (or word) is
- even or odd. The 8086 sets the parity flag after most arithmetic
- and all logical operations. If parity is even, the flag is 1, if
- parity is odd, the flag is 0.
-
-